/*
 * Scheduler.cpp
 *
 *  Created on: 24.09.2012
 *      Author: Lapchinskiy
 */
//#include "Global_includes.h"
//#include "Logging.h"
//#include "Global_includes.h"
#include "BuildConfig.h"
#include "Global_types.h"
#include "ArrayList.h"
#include "Condition.h"
#include "Task.h"
#include "TimeManager.h"
#include "Scheduler.h"
volatile uint32_t Scheduler::eventMask;
ArrayList<Task> * Scheduler::taskLists = NULL;
bool Scheduler::schedEnable=FALSE;

Scheduler::Scheduler() {

}
ErrorCode Scheduler::init(void) {
//	for(uint8_t i=0; i<MAX_EVENT_NUMBER;i++)
	Scheduler::taskLists = new ArrayList<Task> [MAX_EVENT_NUMBER];
	return NO_ERR;

}

ErrorCode Scheduler::start(void) {
	schedEnable=TRUE;
	ErrorCode errCode;
	Task task;
	while (schedEnable) {
		while (!eventMask) { //Waiting for event to occur
			kickTheDog(); //reseting the watchdog
		}
		for (uint8_t i = 0; i < MAX_EVENT_NUMBER; i++) {
			if (eventMask & (uint8_t(1 << i))) { //select event from mask
				eventMask&= (~uint8_t(1 << i)); //clear event from mask
				// TimeManager::enabled=FALSE;
				for (uint8_t j = 0; j < taskLists[i].getLength(); j++) { //all event listener running cycle
					Task *nextTaskInChain = taskLists[i].get(j)->run(); //run event listener and get next task from chain;
					taskLists[i].add(nextTaskInChain,j);
				}
				// TimeManager::enabled=TRUE;
			}
		}
	//	usleep(10);
	}
	return NO_ERR;
}

ErrorCode Scheduler::sendEvent(uint8_t event) {
	Scheduler::eventMask |= uint32_t(1 << event);
	return NO_ERR;
}

ErrorCode Scheduler::waitForEvent(void) {
	while (!eventMask) {

	}
	return NO_ERR;
}

ErrorCode Scheduler::addTask(Task* taskToAdd, EventType eventToListen) {
	taskLists[(uint8_t) eventToListen].add(taskToAdd);
	return NO_ERR;
}

ErrorCode Scheduler::stop(void) {
	schedEnable=FALSE;
	return NO_ERR;
}

ArrayList<Task>* Scheduler::getTaskLists(void) {
	return taskLists;
}

ErrorCode Scheduler::kickTheDog(void) {
	return NO_ERR;
}

Scheduler::~Scheduler() {
	delete[] taskLists;
}

